package org.example.quartz.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.db.Session;
import cn.hutool.db.ds.simple.SimpleDataSource;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.example.quartz.dto.CompanyTask;
import org.example.quartz.dto.TaskInfo;
import org.example.quartz.mode.CronTimingModel;
import org.example.quartz.mode.IntervalTimingMode;
import org.example.quartz.mode.QuartzForm;
import org.example.quartz.mode.TriggerType;
import org.example.quartz.service.QuartzTaskService;
import org.example.quartz.service.UtilService;
import org.example.quartz.task.QuartzTaskJob;
import org.example.quartz.util.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.sql.DataSource;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Slf4j
@RestController("quartzTaskControllerSlave1")
@RequestMapping(path = "/GSYY/quartz")
public class QuartzTaskController {
    @Autowired
    private QuartzTaskService quartzTaskService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Value(value = "${spring.datasource.databaseType}")
    private String databaseType;
    @Value("${spring.datasource.url}")
    private String jdbcUrl;
    @Value("${spring.datasource.username}")
    private String username;
    @Value("${spring.datasource.password}")
    private String password;

    //orgService
    UtilService utilService = SpringUtil.getBean(UtilService.class);

    /**
     * 添加定时任务
     *
     * @param param
     * @return
     */
    @PostMapping("/addTask")
    public JSONObject addTask(@RequestBody QuartzForm param) {
        DataSource ds = new SimpleDataSource(jdbcUrl, username, password);
        try (Session session = Session.create(ds)) {
            // 查询任务类
            Map<String, Object> map = jdbcTemplate.queryForMap("select * from " + utilService.getGSYY() + ".\"task_info\" where \"delete_state\" = 0 and \"use_type\"='GSYY' and \"id\" = ?", param.getTaskInfoId());
            TaskInfo taskInfo = BeanUtil.toBean(map, TaskInfo.class);
            taskInfo.setId(map.get("ID").toString());
            if (null == taskInfo) {
                JSONObject result = new JSONObject();
                result.put("message", "定时创建失败,请联系开发人员!");
                result.put("code", 500);
                return result;
            }

            Class<? extends QuartzTaskJob> quartzClass = (Class<? extends QuartzTaskJob>) Class.forName(taskInfo.getTaskClass());
            // 生产taskName和groupName   taskName全局唯一，但是可以和groupName一样
            String uuid = UUID.randomUUID().toString();
            // cron
            if (1 == param.getType()) {
                CronTimingModel cronTimingModel = new CronTimingModel(quartzClass, uuid, uuid, taskInfo.getTaskDesc(), param.getCronExpression());
                quartzTaskService.addTask(cronTimingModel);
            } else {
                IntervalTimingMode intervalTimingMode = null;
                switch (param.getTriggerType()) {
                    case "毫秒":
                        intervalTimingMode = new IntervalTimingMode(quartzClass, uuid, uuid, taskInfo.getTaskDesc(), TriggerType.INTERVAL_MILLISECOND, param.getInterval(), param.getRepeatCount());
                        break;
                    case "秒":
                        intervalTimingMode = new IntervalTimingMode(quartzClass, uuid, uuid, taskInfo.getTaskDesc(), TriggerType.INTERVAL_SECOND, param.getInterval(), param.getRepeatCount());
                        break;
                    case "分钟":
                        intervalTimingMode = new IntervalTimingMode(quartzClass, uuid, uuid, taskInfo.getTaskDesc(), TriggerType.INTERVAL_MINUTE, param.getInterval(), param.getRepeatCount());
                        break;
                    case "小时":
                        intervalTimingMode = new IntervalTimingMode(quartzClass, uuid, uuid, taskInfo.getTaskDesc(), TriggerType.INTERVAL_HOUR, param.getInterval(), param.getRepeatCount());
                        break;
                    default:
                        break;
                }

                quartzTaskService.addTask(intervalTimingMode);
            }
            if ("oracle".equals(databaseType) || "dm".equals(databaseType)) {
                jdbcTemplate.update("insert into " + utilService.getGSYY() + ".\"company_task\"(\"id\",\"taskname\",\"task_info_id\", \"task_name\",\"task_group\", \"task_state\",\"type\",\"delete_state\") values (?, ?, ?, ?,?, ?,?,?)", String.valueOf(IdUtil.getSnowflakeNextId()).substring(11), param.getTaskName(), taskInfo.getId(), uuid, uuid, "正在运行", "GSYY", 0);
            } else {
                // 存入定时任务所属公司表
                jdbcTemplate.update("insert into " + utilService.getGSYY() + ".company_task(id,taskname,task_info_id, task_name, task_group, task_state,delete_state) values (?, ?, ?, ?, ?,?,?)", String.valueOf(IdUtil.getSnowflakeNextId()).substring(11), param.getTaskName(), taskInfo.getId(), uuid, uuid, "正在运行", 0);
            }
            JSONObject result = new JSONObject();
            result.put("message", "添加任务成功");
            result.put("code", 200);
            result.put("data", uuid);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            JSONObject result = new JSONObject();
            result.put("message", "添加任务失败!");
            result.put("code", 500);
            return result;
        }
    }

    /**
     * 修改定时任务
     *
     * @param param
     * @return
     */
    @PostMapping("/updateTask")
    public JSONObject updateTask(@RequestBody QuartzForm param) {
        DataSource ds = new SimpleDataSource(jdbcUrl, username, password);
        try (Session session = Session.create(ds)) {
            Map<String, Object> map = jdbcTemplate.queryForMap("select * from " + utilService.getGSYY() + ".\"company_task\" where \"delete_state\" = 0 and \"type\"='GSYY' and \"id\" = ?", param.getCompanyTaskId());
            CompanyTask companyTask = BeanUtil.toBean(map, CompanyTask.class);
            // 定时任务信息id
            String taskInfoId = companyTask.getTaskInfoId();
            // 查询任务类
            Map<String, Object> map1 = jdbcTemplate.queryForMap("select * from " + utilService.getGSYY() + ".\"task_info\" where \"delete_state\" = 0 and \"use_type\"='GSYY' and \"id\" = ?", taskInfoId);
            TaskInfo taskInfo = BeanUtil.toBean(map1, TaskInfo.class);

            if (null == taskInfo) {
                JSONObject result = new JSONObject();
                result.put("message", "定时创建失败,请联系开发人员!");
                result.put("code", 500);
                return result;
            }
            Class<? extends QuartzTaskJob> quartzClass = (Class<? extends QuartzTaskJob>) Class.forName(taskInfo.getTaskClass());

            if (1 == param.getType()) {
                CronTimingModel cronTimingModel = new CronTimingModel(quartzClass, companyTask.getTaskGroup(), companyTask.getTaskGroup(), taskInfo.getTaskDesc(), param.getCronExpression());
                quartzTaskService.updateTask(cronTimingModel);
            } else {
                IntervalTimingMode intervalTimingMode = null;
                switch (param.getTriggerType()) {
                    case "毫秒":
                        intervalTimingMode = new IntervalTimingMode(quartzClass, companyTask.getTaskGroup(), companyTask.getTaskGroup(), taskInfo.getTaskDesc(), TriggerType.INTERVAL_MILLISECOND, param.getInterval(), param.getRepeatCount());
                        break;
                    case "秒":
                        intervalTimingMode = new IntervalTimingMode(quartzClass, companyTask.getTaskGroup(), companyTask.getTaskGroup(), taskInfo.getTaskDesc(), TriggerType.INTERVAL_SECOND, param.getInterval(), param.getRepeatCount());

                        intervalTimingMode = new IntervalTimingMode(quartzClass, companyTask.getTaskGroup(), companyTask.getTaskGroup(), taskInfo.getTaskDesc(), TriggerType.INTERVAL_MINUTE, param.getInterval(), param.getRepeatCount());

                        intervalTimingMode = new IntervalTimingMode(quartzClass, companyTask.getTaskGroup(), companyTask.getTaskGroup(), taskInfo.getTaskDesc(), TriggerType.INTERVAL_HOUR, param.getInterval(), param.getRepeatCount());
                        break;
                    default:
                        break;
                }

                quartzTaskService.updateTask(intervalTimingMode);
            }

            if ("oracle".equals(databaseType) || "dm".equals(databaseType)) {
                String udpateSql = "update " + utilService.getGSYY() + ".\"company_task\" set \"task_info_id\" ='" + param.getTaskInfoId() + "', \"taskname\" ='" + param.getTaskName() + "' where \"id\" ='" + param.getCompanyTaskId() + "'";
                jdbcTemplate.update(udpateSql);
                /*Entity entity = Entity.create(utilService.getGSYY()+".company_task");
                entity.set("ID", String.valueOf(IdUtil.getSnowflakeNextId()).substring(11));
                entity.set("taskName", param.getTaskName());
                entity.set("task_info_id", param.getTaskInfoId());
                session.update(entity, Entity.create(utilService.getGSYY()+".company_task").set("id", param.getCompanyTaskId()));*/
            } else {
                // 修改操作
                jdbcTemplate.update("update " + utilService.getGSYY() + ".company_task set task_info_id = ?, taskname = ? where id = ?", param.getTaskInfoId(), param.getTaskName(), param.getCompanyTaskId());
            }


            JSONObject result = new JSONObject();
            result.put("message", "修改任务成功!");
            result.put("code", 200);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            JSONObject result = new JSONObject();
            result.put("message", "修改任务失败!");
            result.put("code", 500);
            return result;
        }
    }


    /**
     * 暂停任务
     *
     * @param param
     * @return
     */
    @PostMapping("/pauseTask")
    public JSONObject pauseTask(@RequestBody QuartzForm param) {
        try {
            Map<String, Object> map = jdbcTemplate.queryForMap("select * from " + utilService.getGSYY() + ".\"company_task\" where \"delete_state\" = 0 and \"id\" = ?", param.getCompanyTaskId());
            CompanyTask companyTask = BeanUtil.toBean(map, CompanyTask.class);
            quartzTaskService.pauseTask(companyTask.getTaskName(), companyTask.getTaskGroup());
            String updateSql = "update " + utilService.getGSYY() + ".\"company_task\" set \"task_state\" = '已暂停' where \"id\" = '" + param.getCompanyTaskId() + "'";
            jdbcTemplate.update(updateSql);
            JSONObject result = new JSONObject();
            result.put("message", "暂停任务成功!");
            result.put("code", 200);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            JSONObject result = new JSONObject();
            result.put("code", 500);
            result.put("message", "暂停任务失败!");
            return result;
        }
    }


    /**
     * 恢复任务
     *
     * @param param
     * @return
     */
    @PostMapping("/resumeTask")
    public JSONObject resumeTask(@RequestBody QuartzForm param) {
        try {
            Map<String, Object> map = jdbcTemplate.queryForMap("select * from " + utilService.getGSYY() + ".\"company_task\" where \"delete_state\" = 0 and \"id\" = ?", param.getCompanyTaskId());
            CompanyTask companyTask = BeanUtil.toBean(map, CompanyTask.class);
            quartzTaskService.resumeTask(companyTask.getTaskName(), companyTask.getTaskGroup());
            String updateSql = "update " + utilService.getGSYY() + ".\"company_task\" set \"task_state\" = '正在运行' where \"id\" = '" + param.getCompanyTaskId() + "'";
            jdbcTemplate.update(updateSql);
            JSONObject result = new JSONObject();
            result.put("message", "恢复任务成功!");
            result.put("code", 200);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            JSONObject result = new JSONObject();
            result.put("message", "恢复任务失败!");
            result.put("code", 500);
            return result;
        }
    }


    /**
     * 删除定时任务
     *
     * @param param
     * @return
     */
    @PostMapping("/deleteTask")
    public JSONObject deleteTask(@RequestBody com.anjiplus.template.gaea.business.modules.quartz.mode.QuartzForm param) {
        try {
            Map<String, Object> map = jdbcTemplate.queryForMap("select * from " + utilService.getGSYY() + ".\"company_task\" where \"delete_state\" = 0 and \"id\" = ?", param.getCompanyTaskId());
            com.anjiplus.template.gaea.business.modules.tbscheduledgaeareport.entity.CompanyTask companyTask = BeanUtil.toBean(map, com.anjiplus.template.gaea.business.modules.tbscheduledgaeareport.entity.CompanyTask.class);
            quartzTaskService.deleteTask(companyTask.getTaskName(), companyTask.getTaskGroup());
            jdbcTemplate.update("update " + utilService.getGSYY() + ".\"company_task\" set \"task_state\" = '已删除', \"delete_state\" = 1 where \"id\" = ?", param.getCompanyTaskId());
            JSONObject result = new JSONObject();
            result.put("message", "删除任务成功!");
            result.put("code", 200);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            JSONObject result = new JSONObject();
            result.put("message", "删除任务失败!");
            result.put("code", 500);
            return result;
        }
    }

    /**
     * 所有任务启动
     *
     * @return
     */
    @PostMapping("/startAllTasks")
    public JSONObject startAllTasks() {
        quartzTaskService.startAllTasks();
        jdbcTemplate.update("update " + utilService.getGSYY() + ".company_task set task_state = '正在运行'");
        JSONObject result = new JSONObject();
        result.put("message", "启动所有任务成功!");
        result.put("code", 200);
        return result;
    }

    /**
     * 关闭所有任务
     *
     * @return
     */
    @PostMapping("/shutdownAllTasks")
    public JSONObject shutdownAllTasks() {
        quartzTaskService.shutdownAllTasks();
        jdbcTemplate.update("update " + utilService.getGSYY() + ".company_task set task_state = '已暂停'");
        JSONObject result = new JSONObject();
        result.put("message", "关闭所有任务成功!");
        result.put("code", 200);
        return result;
    }


    /**
     * 查询列表
     *
     * @param param
     * @return
     */
    @PostMapping("/getList")
    public Result getList(@RequestBody Map<String, Object> param) {
        try {
            String condition = " and \"type\" = '" + param.get("type") + "'";
            //拼接条件
            if (!ObjectUtils.isEmpty(param.get("taskname"))) {
                condition += " and \"taskname\" like '%" + param.get("taskname") + "%'";
            }
            List<Map<String, Object>> mapList = jdbcTemplate.queryForList("select * from " + utilService.getGSYY() + ".\"company_task\" where \"delete_state\" = 0 " + condition);
            return Result.success(mapList);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail(e.getMessage());
        }
    }


    /**
     * 查询单条
     *
     * @param id
     * @return
     */
    @PostMapping("/getById")
    public Result getById(@RequestParam("id") String id) {
        try {
            String sql = "SELECT t.*,t1.CRON_EXPRESSION FROM " + utilService.getGSYY() + ".\"company_task\" t \n" +
                    "LEFT JOIN " + utilService.getGSYY() + ".QRTZ_CRON_TRIGGERS t1  on t1.TRIGGER_GROUP = t.\"task_name\"\n" +
                    "WHERE t.\"delete_state\"=0 \n" +
                    "AND t.\"id\"= '" + id + "'";
            Map<String, Object> map = jdbcTemplate.queryForMap(sql);
            return Result.success(map);
        } catch (EmptyResultDataAccessException empty) {
            return Result.fail("没有数据,id错误！");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail(e.getMessage());
        }
    }


}
